package sfms.controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Time;
import java.sql.Timestamp;
import sfms.model.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import sfms.util.*;

@SuppressWarnings( "deprecation" )
public class Customer implements ControllerBase 
{
    private sfms.view.Customer view;
    private ArrayList<Facility> facilities;
    private ArrayList<Date> days;
    private ArrayList<Venue> venues;
    private ArrayList<String> slots;
    private ArrayList<Booking> bookings;
    private Model model;
    private User user;
    
    
    //Models for the table views
    DefaultTableModel modelBooking;

    public Customer(Model m, User u)
    {
        model = m;
        user = u;
        System.out.println(u.getData());
        view = new sfms.view.Customer(this);
        
        facilities = new ArrayList<Facility>();
        venues = new ArrayList<Venue>();
        days = new ArrayList<Date>();
        bookings = new ArrayList<Booking>();
        
    }
    @Override
    public void show()
    {
        view.setVisible(true);
    }
    
    @Override
    public void hide()
    {
        view.setVisible(false);
        view.dispose();
    }
    
    /**
     * Fill the specified combo box with the required list
     * @param comboBox The combo box to populate
     */
    public void updateComboBox(javax.swing.JComboBox comboBox, int identifier)
    {
        switch (identifier)
        {
            case 0:
                for (Date i : days) {
                    comboBox.addItem(i);
                }
                break;
            case 1:
                for (Facility i : facilities) {
                    comboBox.addItem(i);
                }
                break;
            case 2:
                for (String i : slots) {
                    comboBox.addItem(i);
                }
                break;
            default:
                for (Venue i : venues) {
                    comboBox.addItem(i);
                }
                break;
        }
    }
    
    /**
     * Book an activity.
     */
    public void bookActivity(int venue_id, Time t, java.sql.Date d) {
        Timestamp datetime = new Timestamp(d.getYear(), d.getMonth(), d.getDate(), 
            t.getHours(), t.getMinutes(), 0, 0);
        
        String password = sfms.view.Password.getPassword();
        if (password == null){
            return;
        }
        
        if (model.getUser(user.getUsername(), sfms.util.MD5.encrypt(password.toCharArray())) == null){
            JOptionPane.showMessageDialog(null, "Incorrect Password.");
            return;
        }
        
        if (model.addBooking(user.getUsername(), venue_id, datetime)){
            JOptionPane.showMessageDialog(null, "Booking has been made successfully.");
            view.setActivityOptions(0);
            addBookings();
            view.showBookings();
            
        }
        else{
            JOptionPane.showMessageDialog(null, "There was an error completing your booking.");
        }
        
    }
    
    //** Hooks **//
    /**
     * 
     * @param model tableBookings.getModel();
     */
    public void setBookingModel(DefaultTableModel model){
        modelBooking = model;
    }
    
    /**
     * 
     * @return The action listener for buttonCancelBooking
     */
    public ActionListener getCancelBookingListener(){
        return new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent ae) {
                try{
                    int bookingRow = view.getBookingRow();
                    Integer venueID = (Integer) modelBooking.getValueAt(bookingRow, 0);
                    
                    String retval = sfms.view.Password.getPassword();
                    System.out.println(retval);
                    
                    String password = sfms.util.MD5.encrypt(retval.toCharArray());
                    System.out.println(password);
                    
                    
                    if (model.getUser(user.getUsername(), password) != null){
                        //Password was good
                        if (model.removeBooking(user.getUsername(), venueID)){
                            JOptionPane.showMessageDialog(null, "Your booking has been cancelled.",
                                    "Success", JOptionPane.DEFAULT_OPTION);
                            modelBooking.removeRow(bookingRow);
                            
                            //No row is selected
                            view.setCancelBookingEnabled(false);
                        }
                        else{
                            JOptionPane.showMessageDialog(null, "There was an error cancelling the booking.",
                                    "Error", JOptionPane.DEFAULT_OPTION);
                        }
                    }
                    else{
                        JOptionPane.showMessageDialog(null, "Password incorrect: no changes made.",
                                "Error", JOptionPane.DEFAULT_OPTION);
                    }
                    
                }
                catch (ArrayIndexOutOfBoundsException e){
                    System.out.println("No row selected.");
                }
            }
            
        };
    }
    
    public void addBookings(){
        for (int i = 0; i < modelBooking.getRowCount(); i++){
            modelBooking.removeRow(i);
        }
        List<Booking> bookingList = model.getCurrentBookings(user.getUsername());
        if (bookingList != null){
            for (Booking b: bookingList){
                Object [] data = new Object[]{
                    b.getVenue().getId(),
                    b.getVenue().getFacility().getTitle(),
                    b.getVenue().getTitle(),
                    b.getTime().toString()
                };

                modelBooking.addRow(data);
            }
        }
    }
    
    public void addBookingRow(Booking b){
        Object [] data = new Object[]{
            b.getVenue().getId(),
            b.getVenue().getFacility().getTitle(),
            b.getVenue().getTitle(),
            b.getTime().toString()
        };
        
        modelBooking.addRow(data);
    }
    
    public List<Facility> getFacilities(CustomDate item){
        List<Facility> listFacilities = model.getActiveFacilities(item);
        List<Booking> bookings = model.getCurrentBookings(user.getUsername());

        for(Booking b : bookings){
            Date time = b.getTime();
            if (time.getYear() == item.getYear() &&
                    time.getMonth() == item.getMonth() &&
                    time.getDate() == item.getDate()){
                Facility remove = b.getVenue().getFacility();
                for (Facility f : listFacilities){
                    if (f.getId() == remove.getId()){
                        listFacilities.remove(f);
                        break;
                    }
                }
            }
       }
       
        return listFacilities;
    }
    
    public boolean validateLicense(Facility item) {
        License license = item.getLicense();

        if (license != null) {
            UserLicense ul = model.getUserLicense(user.getUsername(), license.getId());

            if (ul == null) {
                String[] message = license.getTitle().split("_");
                
                if (JOptionPane.showConfirmDialog(null, message,
                        "Need License", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                    UserLicense newUserLicense = new UserLicense(user, license, new Date());
                    JOptionPane.showMessageDialog(null, "You now hold a license for " + item.getTitle(),
                        "Success", JOptionPane.INFORMATION_MESSAGE);
                    
                    return model.addUserLicense(newUserLicense);
                } else {
                    view.resetFacilitySection();
                    return false;
                }
            }

            return true;
        }

        return true;
    }
    
    public List<Time> getSlots(Facility item, CustomDate day){


        return model.getAvailableSlots(item, day);
    }

    public List<Object> getDays(){
        ArrayList<Object> retlist = new ArrayList<Object>();
        
        for(int i = 0; i < 7; i++){
            sfms.util.CustomDate d = new sfms.util.CustomDate(){
            };
            d.setDate(d.getDate()+i);
            retlist.add(d);
        }
        
        return retlist;
    }
    

    public List<Venue> getVenues(Facility f){  
        List<Venue> v = model.getAvailableVenues(f.getId());
        v = new ArrayList<Venue>(new TreeSet<Venue>((Collection<Venue>) v));
        return v;
    }
    
    public boolean changePassword(String password) { 
        return model.changeUserPassword(user.getUsername(), user.getPassword(), MD5.encrypt(password.toCharArray()));
    }

    /**
     * Log out of the application
     */
    public void logout() {
        sfms.controller.Login login = new sfms.controller.Login(model);
        this.hide();
        login.show();
    }
    
    
}
